package com.hyving.home.okhttpdemo.config;

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

@Configuration
public class OkHttpClientSpringConfig {


        @Value("${okhttp.proxy.enable}")
        private boolean enable;
        @Value("${okhttp.proxy.host}")
        private String proxyHost;
        @Value("${okhttp.proxy.port}")
        private int proxyPort;
        @Value("${okhttp.proxy.connectTimeout}")
        private int connectTimeout;
        @Value("${okhttp.proxy.readTimeout}")
        private int readTimeout;
        @Value("${okhttp.proxy.writeTimeout}")
        private int writeTimeout;
        /**
         * 连接池的最大空闲连接数
         */
        @Value("${okhttp.proxy.connectionPool.maxConnect}")
        private int maxConnect;
        /**`
         * 每个连接的最大请求数
         */
        @Value("${okhttp.proxy.connectionPool.keepAlive}")
        private int keepAlive;

        @Bean
        public ConnectionPool pool() {
            return new ConnectionPool(maxConnect, keepAlive, TimeUnit.SECONDS);
        }

        @Bean
        public OkHttpClient okHttpClient() {
                OkHttpClient.Builder builder = new OkHttpClient.Builder()
                        .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                        .callTimeout(connectTimeout, TimeUnit.SECONDS)
                        .connectTimeout(connectTimeout, TimeUnit.SECONDS) // 设置连接超时时间
                        .readTimeout(readTimeout, TimeUnit.SECONDS) // 设置读取超时时间
                        .writeTimeout(writeTimeout, TimeUnit.SECONDS) // 设置写入超时时间
                        .retryOnConnectionFailure(false) // 是否自动重试连接失败的请求
                        .connectionPool(pool()); // 设置连接池;
                if (enable) {
                        builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)));
                }
                return builder.build();
        }

        @Bean
        public X509TrustManager x509TrustManager() {
                return new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType)
                                throws CertificateException {
                        }
                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType)
                                throws CertificateException {
                        }
                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                                return new X509Certificate[0];
                        }
                };
        }
        @Bean
        public SSLSocketFactory sslSocketFactory() {
                try {
                        // 信任任何链接
                        SSLContext sslContext = SSLContext.getInstance("TLS");
                        sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
                        return sslContext.getSocketFactory();
                } catch (NoSuchAlgorithmException | KeyManagementException e) {
                        e.printStackTrace();
                }
                return null;
        }

}
